"""
Case Type   : 故障&可靠性测试
Case Name   : 打印扩容结果-失败
Create At   : 2022/5/16
Owner       : n@ningyali
Description :
    1、准备扩容所用的XML文件
    2、构造扩容失败场景，执行整个扩容流程
    3、查看扩容结果打印情况
Expect      :
    1、准备xml成功
    2、扩容失败
    3、扩容结果打印符合预期
History     :
"""
import os
import re
import time
import unittest
from datetime import datetime

from yat.test import macro

from testcase.utils.ComThread import ComThread
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH, RestartDbCluster
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger


class GsExpansion52(unittest.TestCase):
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.sh = {'pri_root': CommonSH('PrimaryRoot'),
                   'pri_user': CommonSH(self.nodes_tuple[0]),
                   'sta1_root': CommonSH('Standby1Root'),
                   'sta1_user': CommonSH(self.nodes_tuple[1]),
                   'sta2_user': CommonSH(self.nodes_tuple[2])}
        self.node_num = self.sh['pri_user'].get_node_num()
        self.log = Logger()
        self.cons = Constant()
        self.com = Common()
        self.expansion_expect = 'Expansion results:.*:.*Success.*' \
                                'Expansion Finish.'
        text = f'-----{os.path.basename(__file__)} start-----'
        self.log.info(text)

        text = '----预置步骤: 一主两备减容一备，后续用例才能扩容 expect: 成功----'
        self.log.info(text)
        expect_msg = 'Success to drop the target nodes'
        shell_cmd = f'''source {macro.DB_ENV_PATH};
                    expect <<EOF
                    set timeout 300
                    spawn gs_dropnode -U {self.sh['pri_user'].node.ssh_user} \
                    -G {self.sh['pri_user'].node.ssh_user} \
                    -h {self.sh.get("sta1_user").node.ssh_host}
                    expect "*(yes/no)?"
                    send "yes\\n"
                    expect eof''' + "\nEOF\n"
        self.log.info(shell_cmd)
        res = self.com.get_sh_result(self.sh['pri_user'].node, shell_cmd)
        self.assertIn(expect_msg, res, f'执行失败: {text}')

        text = '---预置步骤: 数据库主机解压安装包，以免找不到扩容脚本 expect: 成功---'
        self.log.info(text)
        cmd = f'cd {os.path.dirname(macro.DB_SCRIPT_PATH)} && ' \
            f'tar -xf openGauss-Package-bak*.tar.gz && ' \
            f'ls {macro.DB_SCRIPT_PATH}|grep gs_sshexkey'
        self.log.info(cmd)
        res = self.com.get_sh_result(self.sh.get("pri_root").node, cmd)
        self.assertEqual(res, 'gs_sshexkey', f'执行失败: {text}')

        text = '----预置步骤: 建立root互信 expect: 成功----'
        self.log.info(text)
        ssh_cmd = f'cd {macro.DB_SCRIPT_PATH};' \
            f'echo "{self.sh.get("pri_root").node.ssh_host}\n' \
            f'{self.sh.get("sta1_user").node.ssh_host}\n' \
            f'{self.sh.get("sta2_user").node.ssh_host}" > hosts\n'
        ssh_cmd += f'''expect <<EOF
                            set timeout 300
                            spawn ./gs_sshexkey -f hosts
                            expect "*assword:"
                            send "{self.sh.get(
            "pri_root").node.ssh_password}\\n"
                            expect eof''' + "\nEOF\n"
        ssh_cmd += "source ~/.bashrc"
        self.log.info(ssh_cmd)
        res = self.com.get_sh_result(self.sh.get("pri_root").node, ssh_cmd)
        self.assertIn('Successfully created SSH trust', res, f'执行失败: {text}')

    def test_1(self):
        text = '----step1: 准备扩容所用的XML文件（延用安装时xml） expect: 准备xml成功----'
        self.log.info(text)
        self.xml_path = macro.DB_XML_PATH

        text = '----step2: 构造扩容失败场景，执行整个扩容流程 expect: 备机扩容失败----'
        self.log.info(text)
        self.expansion_cmd = f'cd {macro.DB_SCRIPT_PATH};' \
            f'source {macro.DB_ENV_PATH}\n' \
            f'./gs_expansion -U {self.sh.get("pri_user").node.ssh_user} ' \
            f'-G {self.sh.get("pri_user").node.ssh_user} ' \
            f'-X {self.xml_path} ' \
            f'-h {self.sh.get("sta1_user").node.ssh_host} -L'
        self.log.info(self.expansion_cmd)
        expansion_thread = ComThread(self.com.get_sh_result, args=(
            self.sh.get("pri_root").node, self.expansion_cmd,))
        expansion_thread.setDaemon(True)
        expansion_thread.start()

        time.sleep(30)

        self.log.info("主节点ctrl+C")
        kill_cmd = f"ps -ef|grep -v grep|grep expansion|" \
            f"grep \"{self.xml_path}\"|" \
            f"awk '{{{{print $2}}}}'|xargs kill -2"
        self.log.info(kill_cmd)
        res = self.com.get_sh_result(self.sh.get("pri_root").node, kill_cmd)
        self.assertEqual(len(res), 0, f'执行失败: {text}')

        self.log.info("获取扩容结果")
        expansion_thread.join(900)
        expansion_res = expansion_thread.get_result()
        self.log.info(expansion_res)
        self.assertIn('KeyboardInterrupt', expansion_res, f'执行失败: {text}')

    def tearDown(self):
        text = '----run teardown----'
        self.log.info(text)

        text1 = '----后置操作: 备机扩容还原集群 expect: 备机扩容成功----'
        self.log.info(text1)
        self.log.info(self.expansion_cmd)
        res = self.com.get_sh_result(self.sh.get("pri_root").node,
                                     self.expansion_cmd)
        regex_res = re.search(self.expansion_expect, res, re.S)

        text2 = '----检查集群状态是否正常----'
        self.log.info(text2)
        res2 = self.sh['pri_user'].getDbClusterStatus('detail')
        self.log.info(res2)

        self.assertIsNotNone(regex_res, f'执行失败: {text1}')
        self.assertEqual(res2.count('Normal'), self.node_num + 1,
                         f'执行失败: {text2}')

        text = f'-----{os.path.basename(__file__)} end-----'
        self.log.info(text)
